home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / zoo / fiz.c < prev    next >
C/C++ Source or Header  |  1980-01-02  |  6KB  |  234 lines

  1. #ifndef LINT
  2. static char sccsid[]="@(#) fiz.c 2.6 88/01/31 23:23:50";
  3. #endif /* LINT */
  4.  
  5. /*
  6. The contents of this file are hereby released to the public domain.
  7.  
  8.                                               -- Rahul Dhesi 1987/02/06
  9. */
  10.  
  11. /*
  12. Searches for all directory entries in an archive and prints their
  13. offsets.  Zoo 1.41 and later may then be asked to extract a specific
  14. file by supplying the offset of the file.
  15. */
  16.  
  17. #include "options.h"
  18. #include "zooio.h"
  19. #include "various.h"
  20. #include "zoofns.h"
  21. #include "portable.h"         /* I/O definitions */
  22. #include "zoo.h"
  23.  
  24. void prtctrl PARMS((char *));
  25. void prtch PARMS((unsigned int));
  26.  
  27. int verbose = 1;
  28.  
  29. main(argc,argv)
  30. register int argc;
  31. register char **argv;
  32. {
  33.     char *zooname;             /* name of archive to be read */
  34.     ZOOFILE zoo_file;         /* the archive being examined opened for read */
  35.     int state;                    /* to keep track of how much of tag seen */
  36.     int inch;                    /* char just read from archive */
  37.  
  38.     static char usage1[] = "Fiz 2.0 (1987/02/01) public domain Zoo archive repair utility by Rahul Dhesi\n";
  39.     static char usage2[] = "Usage:  fiz archive[.zoo]  (\"fiz -h\" for help)\n";
  40.  
  41. #ifdef SETBUF
  42. /* set stdout to unbuffered */
  43. setbuf (stdout, (char *) NULL);
  44. #endif
  45.  
  46.     if (argc < 2) {
  47.         printf("%s%s", usage1, usage2);
  48.         exit (1);
  49.     }
  50.  
  51.     if (strcmp(argv[1],"-h") == 0)
  52.         goto givehelp;
  53.  
  54.     zooname = argv[1];
  55.  
  56.     /* Add default extension if none supplied */
  57.     {
  58.         char *p, *q;
  59.         p = zooname + strlen(zooname);         /* point to last char */
  60.         while (p != zooname && *p != EXT_CH)
  61.             --p;
  62.         /* either found EXT_CH or reached beginning of zooname */
  63.         if (*p != EXT_CH) {
  64.             q = malloc(strlen(zooname) + strlen(EXT_DFLT) + 2);
  65.             if (q == NULL) {
  66.                 printf("Fiz:  Ran out of memory.\n");
  67.                 exit(1);
  68.             }
  69.             strcpy(q, zooname);
  70.             strcat(q, EXT_DFLT);
  71.             zooname = q;
  72.         }
  73.     }
  74.  
  75.     zoo_file = zooopen (zooname, Z_READ);
  76.     if (zoo_file == NOFILE) {
  77.         printf("Fiz:  FATAL:  Could not open %s.\n", zooname);
  78.         exit(1);
  79.     }
  80.  
  81. #ifdef DOUBLE_SECRET
  82.     { void oh_well(void); oh_well(); }
  83. #endif
  84.  
  85. #define    NOSTATE    1
  86. #define    HDR_1   0xdc
  87. #define    HDR_2   0xa7
  88. #define    HDR_3   0xc4
  89. #define    HDR_4   0xfd
  90.  
  91. #define    DAT_1   '@'
  92. #define    DAT_2   ')'
  93. #define    DAT_3   '#'
  94. #define    DAT_4   '('
  95.  
  96. /* finite state machine implemented here by hand */
  97.  
  98.     state = NOSTATE;
  99.     while ((inch = zgetc(zoo_file)) != EOF) {
  100.         inch = inch & 0xff;
  101.         if (state == NOSTATE) {
  102.             if (inch == HDR_1)
  103.                 state = HDR_1;
  104.             else if (inch == DAT_1)
  105.                 state = DAT_1;
  106.         } else if (state == HDR_1 && inch == HDR_2)
  107.             state = HDR_2;
  108.         else if (state == HDR_2 && inch == HDR_3)
  109.             state = HDR_3;
  110.         else if (state == HDR_3 && inch == HDR_4)
  111.             state = HDR_4;
  112.         else if (state == DAT_1 && inch == DAT_2)
  113.             state = DAT_2;
  114.         else if (state == DAT_2 && inch == DAT_3)
  115.             state = DAT_3;
  116.         else if (state == DAT_3 && inch == DAT_4)
  117.             state = DAT_4;
  118.         else
  119.             state = NOSTATE;
  120.  
  121.         if (state == HDR_4) {                           /* found archive tag */
  122.             long save_pos;
  123.             struct direntry direntry;
  124.             save_pos = zootell(zoo_file);
  125.             zooseek(zoo_file, save_pos-4L, 0);           /* back to tag pos */
  126.             frd_dir(&direntry, zoo_file);                /* read dir entry */
  127.             printf("****************\n");
  128.  
  129.             printf ("%8lu: DIR ", save_pos-4L);
  130.  
  131.             if (direntry.dirlen > 0) {
  132.                 printf ("[");
  133.                 prtctrl (direntry.dirname);
  134.                 printf ("]");
  135.             }
  136.  
  137.             printf(" [");
  138.             prtctrl (direntry.fname);
  139.             printf ("]");
  140.  
  141.             if (direntry.namlen > 0) {
  142.                 printf (" [");
  143.                 prtctrl (direntry.lfname);
  144.                 printf ("]");
  145.             }
  146.             printf (" ==> %4lu", direntry.offset);
  147.             if (direntry.dir_crc != 0)
  148.                 printf (" [*bad CRC*]");
  149.             printf ("\n");
  150.             fseek (zoo_file, save_pos, 0);         /* try again from there */
  151.         } else if (state == DAT_4) {           /* file data */
  152.             printf ("%8lu: DATA\n", zootell(zoo_file) + 1);
  153.         }
  154.     }
  155. exit (0);      /* don't fall through */
  156.  
  157. givehelp:
  158.  
  159. /*
  160. vi macros:
  161. to add printf:
  162. :s/^.*$/printf("&\\n");/
  163. To remove printf:
  164. :s/^printf("\(.*\)\\n");/\1/
  165. */
  166. printf("Fiz is used to help you recover data from a damaged archive.  Fiz searches\n");
  167. printf("the specified archive for directory entries and stored files, and prints the\n");
  168. printf("position of each one found.  Each directory entry contains a number that\n");
  169. printf("represents the location in the archive where the file is stored;  fiz also\n");
  170. printf("prints this position.  All numbers printed are decimal numbers.\n\n");
  171.  
  172. printf("Use Zoo version 2.00 or higher to list or extract files in the damaged\n");
  173. printf("archive starting at a position identified by fiz.  For example, you can\n");
  174. printf("start extracting files from archive \"badarc.zoo\" at position 1098 with the\n");
  175. printf("command:\n\n");
  176.  
  177. printf("     zoo x@1098 badarc\n\n");
  178.  
  179. printf("Zoo will ignore the first 1098 bytes of the damaged archive and you should be\n");
  180. printf("able to recover the undamaged files from the rest of the archive.  You can\n");
  181. printf("also manually specify where to look for the file data with a command like\n\n");
  182.  
  183. printf("     zoo x@1098,1153\n\n");
  184.  
  185. printf("which tells zoo to use the directory entry at position 1098, but to get the\n");
  186. printf("actual file data from position 1153 (and not from where the directory entry\n");
  187. printf("says the data ought to be).  See the manuals for fiz and zoo for more details.\n");
  188.  
  189. exit (0);
  190. }
  191.  
  192. /*
  193. prtctrl() prints a string with all unprintable characters converted
  194. to printable form.  To avoid the program running astray trying to
  195. print damaged data, no more than MAXPRT characters are printed.
  196. Characters with the 8th bit set are printed preceded with ~.  Control
  197. characters are printed preceded with ^.  Both ~ and ^ may preced
  198. the character if a control character has the 8th bit set.
  199. */
  200. #define    MAXPRT        50
  201.  
  202. void prtctrl (str)
  203. char *str;
  204. {
  205.     unsigned int ch;
  206.     int count;
  207.     count = 0;
  208.  
  209.     while (count < MAXPRT && *str != '\0') {
  210.         ch = (unsigned) *str;
  211.         prtch(ch);
  212.         str++;
  213.         count++;
  214.     }
  215. }
  216.  
  217. /*
  218. Does the actual character printing for prtctrl()
  219. */
  220. void prtch(ch)
  221. unsigned int ch;
  222. {
  223.     /* assumes ASCII character set */
  224.     if (ch < ' ') {                        /* ^@ through ^_ */
  225.         printf("^%c", ch + 0x40);
  226.     } else if (ch == 0x7f) {               /* DEL */
  227.         printf("^?");
  228.     } else if (ch > 0x7f) {                /* 8th bit set */
  229.         printf("~");                        /* .. so precede with ~ */
  230.         prtch(ch & 0x7f);                   /* slick recursive call */
  231.     } else
  232.         printf("%c", ch);                   /* plain char */
  233. }
  234.